package com.such.kit.io.bean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.annotation.JSONField;
import com.such.kit.io.simple.support.IOSimple;
import com.such.kit.io.source.DatabaseIOSource;
import com.such.kit.placeholder.PlaceholderCommons;
import com.such.kit.string.StringCommons;
import com.such.kit.validate.ValidateCommons;

/**
 * @author SUCH
 * <pre>
 * TextIOConfig 定义了 {@link #mode 2} 大类文本文件 IO 模式，不同模式会有些更细 {@link #modeParam 配置项}
 * </pre>
 */
public class TextIOConfig {

	public static final String IO_FILE_TYPE = "IO_FILE_TYPE";
	public static final String IO_FILE_TYPE_TXT = "txt";
	public static final String IO_CHARSET = "IO_CHARSET";
	public static final String IO_MODE = "IO_MODE";
	/** IO_MODE_WIDTH：等宽模式 */
	public static final String IO_MODE_WIDTH = "width";
	/** IO_MODE_SEPARATE：分隔符模式 */
	public static final String IO_MODE_SEPARATE = "separate";
	public static final String IO_MODE_PARAM = "IO_MODE_PARAM";
	/**
	 * IO_MODE_PARAM_WIDTH_STRICTLY：是否使用精确等宽计算 [N | Y] [默认值为 N]
	 * <pre>
	 * 精确等宽计算会根据 {@link #charset} 计算方块字 Byte 长度
	 * 比如 GBK 编码下方块字长度为 2，UTF-8 编码下方块字长度为 3
	 * </pre>
	 */
	public static final String IO_MODE_PARAM_WIDTH_STRICTLY = "strictly";
	/** IO_MODE_PARAM_SEPARATE_SEPARATOR：数据（字段）间分隔符 */
	public static final String IO_MODE_PARAM_SEPARATE_SEPARATOR = "separator";
	/** IO_MODE_PARAM_SEPARATE_QUALIFIER：数据（字段）界定符，界定符用于界定一个数据（字段）的开始、结束 [可空] */
	public static final String IO_MODE_PARAM_SEPARATE_QUALIFIER = "qualifier";
	public static final String IO_TITLE_TEMPLATE = "IO_TITLE_TEMPLATE";
	public static final String IO_DATA_TEMPLATE = "IO_DATA_TEMPLATE";
	public static final String IO_ROW_QUALIFIER = "IO_ROW_QUALIFIER";
	public static final String IO_INPUT_EXPRESSION = "IO_INPUT_EXPRESSION";
	public static final String IO_OUTPUT_EXPRESSION = "IO_OUTPUT_EXPRESSION";
	public static final String IO_IGNORE_ROW = "IO_IGNORE_ROW";

	/** fileType：文件类型 [默认值为 {@link #IO_FILE_TYPE_TXT}] */
	@JSONField(name = IO_FILE_TYPE)
	private String fileType = IO_FILE_TYPE_TXT;
	/** charset：数据文件编码 [默认值为 {@link StringCommons#CHARSET_GBK}] [参考 {@link StringCommons}.ENCODE_*] */
	@JSONField(name = IO_CHARSET)
	private String charset = StringCommons.CHARSET_GBK;
	/** mode：IO 模式 [{@link #IO_MODE_WIDTH} | {@link #IO_MODE_SEPARATE}] */
	@JSONField(name = IO_MODE)
	private String mode;
	/**
	 * modeParam：IO 模式参数
	 * <pre>
	 * width 等宽模式需要设置是否开启 {@link #IO_MODE_PARAM_WIDTH_STRICTLY 精确等宽计算} 以及每个字段的宽度
	 * [举例] {strictly: "Y", schema: "10", tableName: "30", tableComment: "100"}
	 * 
	 * separate 分隔符模式需要设置 {@link #IO_MODE_PARAM_SEPARATE_SEPARATOR 数据（字段）间分隔符} 以及 {@link #IO_MODE_PARAM_SEPARATE_QUALIFIER 数据（字段）界定符}
	 * [举例] {separator: ",", qualifier: "\""}
	 * </pre>
	 */
	@JSONField(name = IO_MODE_PARAM)
	private Map<String, String> modeParam;
	/** ignoreRow：[导入时] 忽略多少行 [下标 1] [默认值为 0] */
	@JSONField(name = IO_IGNORE_ROW)
	private int ignoreRow = 0;
	/**
	 * titleTemplate：[导出时] 表头模板
	 * <pre>
	 * [警告] titleTemplate 与 dataTemplate 必须一一对应，否则会导致表头与数据错行，系统会避免错行产生而输出空表头
	 * [举例] ["用户名", "表名", "表说明"]
	 * </pre>
	 */
	@JSONField(name = IO_TITLE_TEMPLATE)
	private List<String> titleTemplate;
	/**
	 * dataTemplate：数据行模板，可以使用 {@link PlaceholderCommons 占位符} 引用 IO 数据、{@link IOSimple#args 自定义参数}
	 * <pre>
	 * [警告] 所有的列都必须设置占位符，否则在导入时会出现错列的问题
	 * [举例] "\"#[schema]\", \"#[tableName]\", \"#[tableComment]\""
	 * </pre>
	 */
	@JSONField(name = IO_DATA_TEMPLATE)
	private String dataTemplate;
	/** rowQualifier：行界定符，行界定符用于界定一行数据的结束 [默认值为 \r] */
	@JSONField(name = IO_ROW_QUALIFIER)
	private String rowQualifier = "\r";
	/**
	 * inputExpression：[导入时] 表达式
	 * <pre>
	 * {@link IOSource} 的不同实现 inputExpression 的推荐值有所变化
	 * 以 {@link DatabaseIOSource} 为例，inputExpression 的推荐值为 sql 语句
	 * [举例] ["insert into TABLE_INFO (schema, name, comment) value (:schema, :tableName, :tableComment)"]
	 * </pre>
	 */
	@JSONField(name = IO_INPUT_EXPRESSION)
	private List<String> inputExpression;
	/**
	 * outputExpression：[导出时] 表达式
	 * <pre>
	 * {@link IOSource} 的不同实现 outputExpression 的推荐值有所变化
	 * 以 {@link DatabaseIOSource} 为例，outputExpression 的推荐值为 sql 语句
	 * [举例] "select schema as schema, name as tableName, comment as tableComment from TABLE_INFO"
	 * </pre>
	 */
	@JSONField(name = IO_OUTPUT_EXPRESSION)
	private String outputExpression;

	/** [参考 {@link #fileType}] */
	public String getFileType() {
		return this.fileType;
	}

	/** [参考 {@link #fileType}] */
	public void setFileType(String fileType) {
		this.fileType = fileType;
	}

	/** [参考 {@link #charset}] */
	public String getCharset() {
		return this.charset;
	}

	/** [参考 {@link #charset}] */
	public void setCharset(String charset) {
		this.charset = charset;
	}

	/** [参考 {@link #mode}] */
	public String getMode() {
		return this.mode;
	}

	/** [参考 {@link #mode}] */
	public void setMode(String mode) {
		this.mode = mode;
	}

	/** [参考 {@link #modeParam}] */
	public Map<String, String> getModeParam() {
		return this.modeParam;
	}

	/** [参考 {@link #modeParam}] */
	public void setModeParam(Map<String, String> modeParam) {
		this.modeParam = modeParam;
	}

	/** [参考 {@link #modeParam}] */
	public void addModeParam(String key, String value) {
		if (ValidateCommons.isEmpty(this.modeParam)) {
			this.modeParam = new HashMap<String, String>();
		}
		this.modeParam.put(key, value);
	}

	/** [参考 {@link #ignoreRow}] */
	public int getIgnoreRow() {
		return this.ignoreRow;
	}

	/** [参考 {@link #ignoreRow}] */
	public void setIgnoreRow(int ignoreRow) {
		this.ignoreRow = ignoreRow;
	}

	/** [参考 {@link #titleTemplate}] */
	public List<String> getTitleTemplate() {
		return this.titleTemplate;
	}

	/** [参考 {@link #titleTemplate}] */
	public void setTitleTemplate(List<String> titleTemplate) {
		this.titleTemplate = titleTemplate;
	}

	/** [参考 {@link #dataTemplate}] */
	public String getDataTemplate() {
		return this.dataTemplate;
	}

	/** [参考 {@link #dataTemplate}] */
	public void setDataTemplate(String dataTemplate) {
		this.dataTemplate = dataTemplate;
	}

	/** [参考 {@link #rowQualifier}] */
	public String getRowQualifier() {
		return this.rowQualifier;
	}

	/** [参考 {@link #rowQualifier}] */
	public void setRowQualifier(String rowQualifier) {
		this.rowQualifier = rowQualifier;
	}

	/** [参考 {@link #inputExpression}] */
	public List<String> getInputExpression() {
		return this.inputExpression;
	}

	/** [参考 {@link #inputExpression}] */
	public void setInputExpression(List<String> inputExpression) {
		this.inputExpression = inputExpression;
	}

	/** [参考 {@link #inputExpression}] */
	public void addInputExpression(String ie) {
		if (ValidateCommons.isEmpty(this.inputExpression)) {
			this.inputExpression = new ArrayList<String>();
		}
		this.inputExpression.add(ie);
	}

	/** [参考 {@link #outputExpression}] */
	public String getOutputExpression() {
		return this.outputExpression;
	}

	/** [参考 {@link #outputExpression}] */
	public void setOutputExpression(String outputExpression) {
		this.outputExpression = outputExpression;
	}

}
